在学习falsk过程中,不可避免会遇到上下文,g,现在了深入了解一下它们的实现原理。其实它们都是一套班子。
# flask.globals.py # context locals _request_ctx_stack = LocalStack() _app_ctx_stack = LocalStack() current_app = LocalProxy(_find_app) request = LocalProxy(partial(_lookup_req_object, "request")) session = LocalProxy(partial(_lookup_req_object, "session")) g = LocalProxy(partial(_lookup_app_object, "g"))重点概念local,localstack,localproxy。
2. local class Local(object): __slots__ = ("__storage__", "__ident_func__") def __init__(self): object.__setattr__(self, "__storage__", {}) object.__setattr__(self, "__ident_func__", get_ident) def __iter__(self): return iter(self.__storage__.items()) def __call__(self, proxy): """Create a proxy for a name.""" return LocalProxy(self, proxy) def __release_local__(self): self.__storage__.pop(self.__ident_func__(), None) def __getattr__(self, name): try: return self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name) def __setattr__(self, name, value): ident = self.__ident_func__()# 获取当前线程/协程的id storage = self.__storage__ # 具体存储信息的dict try: # 处理ident不存在于storage中的情况 storage[ident][name] = value except KeyError: storage[ident] = {name: value} def __delattr__(self, name): try: del self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name)它的主要属性如下:Local().storage = {ident_1:dict1, ident_2:dict2}ident_1/2为线程号/协程号取值时也是根据线程号找到对应的dict.name
另外需要说明的是ident获取方法